home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
UNIX
/
PASCAL
/
PTOC
/
PTC_C.1
< prev
next >
Wrap
Text File
|
1992-11-23
|
34KB
|
1,501 lines
/***************************************************************************/
/***************************************************************************/
/** **/
/** Copyright (C) 1987 by Per Bergsten, Gothenburg, Sweden **/
/** **/
/** No part of this program, or parts derived from this program, **/
/** may be sold, hired or otherwise exploited without the author's **/
/** written consent. **/
/** **/
/** The program may be freely redistributed provided that: **/
/** **/
/** 1) the original program text, including this notice, **/
/** is reproduced unaltered, **/
/** 2) no charge (other than a nominal media cost) is **/
/** demanded for the copy. **/
/** **/
/** The program may be included in a package only on the condition **/
/** that the package as a whole is distributed at media cost. **/
/** **/
/***************************************************************************/
/***************************************************************************/
/** **/
/** The program is a Pascal-to-C translator. **/
/** It accepts a correct Pascal program and creates a C program **/
/** with the same behaviour. It is not a complete compiler in the **/
/** sense that it does NOT do complete typechecking or error- **/
/** reporting. Only a minimal typecheck is done so that the meaning **/
/** of each construct can be determined. Therefore, an incorrect **/
/** Pascal program can easily cause the translator to malfunction. **/
/** **/
/***************************************************************************/
/***************************************************************************/
/** **/
/** Things which are known to be dependent on the underlying cha- **/
/** racterset are marked with a comment containing the word CHAR. **/
/** Things that are known to be dependent on the host operating **/
/** system are marked with a comment containing the word OS. **/
/** Things known to be dependent on the cpu and/or the target C- **/
/** implementation are marked with the word CPU. **/
/** Things dependent on the target C-library are marked with LIB. **/
/** **/
/** The code generated by the translator assumes that there is a **/
/** C-implementation with at least a reasonable <stdio> library **/
/** since all input/output is implemented in terms of C functions **/
/** like fprintf(), getc(), fopen(), rewind() etc. **/
/** If the source-program uses Pascal functions like sin(), sqrt() **/
/** etc, there must also exist such functions in the C-library. **/
/** **/
/***************************************************************************/
/***************************************************************************/
/*
** Code derived from program ptc
*/
extern void exit();
/*
** Definitions for i/o
*/
# include <stdio.h>
typedef struct {
FILE *fp;
unsigned short eoln:1,
eof:1,
out:1,
init:1,
:12;
char buf;
} text;
text input = { stdin, 0, 0 };
text output = { stdout, 0, 0 };
# define Fread(x, f) fread((char *)&x, sizeof(x), 1, f)
# define Get(f) Fread((f).buf, (f).fp)
# define Getx(f) (f).init = 1, (f).eoln = (((f).buf = fgetc((f).fp)) == '\n') ? (((f).buf = ' '), 1) : 0
# define Getchr(f) (f).buf, Getx(f)
static FILE *Tmpfil;
static long Tmplng;
static double Tmpdbl;
# define Fscan(f) (f).init ? ungetc((f).buf, (f).fp) : 0, Tmpfil = (f).fp
# define Scan(p, a) Scanck(fscanf(Tmpfil, p, a))
void Scanck();
# define Eoln(f) ((f).eoln ? true : false)
# define Eof(f) ((((f).init == 0) ? (Get(f)) : 0, ((f).eof ? 1 : feof((f).fp))) ? true : false)
# define Fwrite(x, f) fwrite((char *)&x, sizeof(x), 1, f)
# define Put(f) Fwrite((f).buf, (f).fp)
# define Putx(f) (f).eoln = ((f).buf == '\n'), (void)fputc((f).buf, (f).fp)
# define Putchr(c, f) (f).buf = (c), Putx(f)
# define Putl(f, v) (f).eoln = v
/*
** Definitions for case-statements
** and for non-local gotos
*/
# define Line __LINE__
void Caseerror();
# include <setjmp.h>
static struct Jb { jmp_buf jb; } J[1];
/*
** Definitions for standard types
*/
extern int strncmp();
# define Cmpstr(x, y) strncmp((x), (y), sizeof(x))
typedef char boolean;
# define false (boolean)0
# define true (boolean)1
extern char *Bools[];
typedef int integer;
# define maxint 2147483647
extern void abort();
/*
** Definitions for pointers
*/
# ifndef Unionoffs
# define Unionoffs(p, m) (((long)(&(p)->m))-((long)(p)))
# endif
# define NIL 0
extern char *malloc();
/*
** Definitions for set-operations
*/
# define Claimset() (void)Currset(0, (setptr)0)
# define Newset() Currset(1, (setptr)0)
# define Saveset(s) Currset(2, s)
# define setbits 15
typedef unsigned short setword;
typedef setword * setptr;
boolean Member(), Le(), Ge(), Eq(), Ne();
setptr Union(), Diff();
setptr Insmem(), Mksubr();
setptr Currset(), Inter();
static setptr Tmpset;
extern setptr Conset[];
void Setncpy();
extern char *strncpy();
/*
** Start of program definitions
*/
static char version[] = "From: @(#)ptc.p 1.5 Date 87/05/01";
static char sccsid[] = "@(#)ptc.c 1.2 Date 87/05/09";
# define keytablen 38
# define keywordlen 10
static char othersym[] = "otherwise ";
static char externsym[] = "external ";
static char dummysym[] = " ";
static char wordtype[] = "unsigned short";
# define C37_setbits 15
static char filebits[] = "unsigned short";
# define filefill 12
# define maxsetrange 15
# define scalbase 0
# define maxprio 7
# define maxmachdefs 8
# define machdeflen 16
# define maxstrblk 1023
# define maxblkcnt 63
# define maxstrstor 65535
# define maxtoknlen 127
# define hashmax 64
# define null 0
# define minchar null
# define maxchar 127
static char tmpfilename[] = "\"/tmp/ptc%d%c\", getpid(), ";
# define space ' '
# define tab1 ' '
static char tab2[] = " ";
static char tab3[] = " ";
static char tab4[] = " ";
# define bslash '\\'
static char nlchr[] = "'\\n'";
static char ffchr[] = "'\\f'";
static char nulchr[] = "'\\0'";
static char spchr[] = "' '";
# define quote '\''
# define cite '"'
# define xpnent 'e'
# define percent '%'
# define uscore '_'
# define badchr '?'
# define okchr quote
# define tabwidth 8
# define echo false
# define diffcomm false
# define lazyfor false
# define unionnew true
static char inttyp[] = "int";
static char chartyp[] = "char";
static char setwtyp[] = "setword";
static char setptyp[] = "setptr";
static char floattyp[] = "float";
static char doubletyp[] = "double";
static char dblcast[] = "(double)";
# define realtyp doubletyp
static char voidtyp[] = "void";
static char voidcast[] = "(void)";
# define intlen 10
# define fixlen 20
static char C24_include[] = "# include ";
static char C4_define[] = "# define ";
static char ifdef[] = "# ifdef ";
static char ifndef[] = "# ifndef ";
static char elsif[] = "# else";
static char endif[] = "# endif";
static char C50_static[] = "static ";
static char xtern[] = "extern ";
static char typdef[] = "typedef ";
static char registr[] = "register ";
# define indstep 8
typedef unsigned char hashtyp;
typedef unsigned short strindx;
typedef unsigned short strbidx;
typedef struct { char A[maxstrblk + 1]; } strblk;
typedef strblk * strptr;
typedef unsigned char strbcnt;
typedef struct S59 * idptr;
typedef struct S59 {
idptr inext;
unsigned char inref;
hashtyp ihash;
strindx istr;
} idnode;
typedef unsigned char toknidx;
typedef struct { char A[maxtoknlen - 1 + 1]; } toknbuf;
typedef struct { char A[keywordlen - 1 + 1]; } keyword;
typedef enum { dabs, darctan, dargc, dargv,
dboolean, dchar, dchr, dclose,
dcos, ddispose, deof, deoln,
dexit, dexp, dfalse, dflush,
dget, dhalt, dinput, dinteger,
dln, dmaxint, dmessage, dnew,
dodd, dord, doutput, dpage,
dpack, dpred, dput, dread,
dreadln, dreal, dreset, drewrite,
dround, dsin, dsqr, dsqrt,
dsucc, dtext, dtrue, dtrunc,
dtan, dwrite, dwriteln, dunpack,
dzinit, dztring } predefs;
typedef enum { sand, sarray, sbegin, scase,
sconst, sdiv, sdo, sdownto,
selse, send, sextern, sfile,
sfor, sforward, sfunc, sgoto,
sif, sinn, slabel, smod,
snil, snot, sof, sor,
sother, spacked, sproc, spgm,
srecord, srepeat, sset, sthen,
sto, stype, suntil, svar,
swhile, swith, seof, sinteger,
sreal, sstring, schar, sid,
splus, sminus, smul, squot,
sarrow, slpar, srpar, slbrack,
srbrack, seq, sne, slt,
sle, sgt, sge, scomma,
scolon, ssemic, sassign, sdotdot,
sdot } symtyp;
typedef struct { setword S[6]; } symset;
typedef struct S180 {
symtyp st;
union {
struct {
idptr vid;
} V1;
struct {
char vchr;
} V2;
struct {
integer vint;
} V3;
struct {
strindx vflt;
} V4;
struct {
strindx vstr;
} V5;
} U;
} lexsym;
typedef enum { lpredef, lidentifier, lfield, lforward,
lpointer, lstring, llabel, lforwlab,
linteger, lreal, lcharacter } ltypes;
typedef struct S60 * declptr;
typedef struct S61 * treeptr;
typedef struct S62 * symptr;
typedef struct S62 {
treeptr lsymdecl;
symptr lnext;
declptr ldecl;
ltypes lt;
union {
struct {
idptr lid;
boolean lused;
} V6;
struct {
strindx lstr;
} V7;
struct {
strindx lfloat;
} V8;
struct {
integer lno;
boolean lgo;
} V9;
struct {
integer linum;
} V10;
struct {
char lchar;
} V11;
} U;
} symnode;
typedef struct S60 {
declptr dprev;
struct { symptr A[hashmax + 1]; } ddecl;
} declnode;
typedef enum { npredef, npgm, nfunc, nproc,
nlabel, nconst, ntype, nvar,
nvalpar, nvarpar, nparproc, nparfunc,
nsubrange, nvariant, nfield, nrecord,
narray, nconfarr, nfileof, nsetof,
nbegin, nptr, nscalar, nif,
nwhile, nrepeat, nfor, ncase,
nchoise, ngoto, nwith, nwithvar,
nempty, nlabstmt, nassign, nformat,
nin, neq, nne, nlt,
nle, ngt, nge, nor,
nplus, nminus, nand, nmul,
ndiv, nmod, nquot, nnot,
numinus, nuplus, nset, nrange,
nindex, nselect, nderef, ncall,
nid, nchar, ninteger, nreal,
nstring, nnil, npush, npop,
nbreak } treetyp;
typedef enum { tnone, tboolean, tchar, tinteger,
treal, tstring, tnil, tset,
ttext, tpoly, terror } pretyps;
typedef enum { anone, aregister, aextern, areference } attributes;
typedef struct S61 {
treeptr tnext, ttype, tup;
treetyp tt;
union {
struct {
predefs tdef;
pretyps tobtyp;
} V12;
struct {
treeptr tsubid, tsubpar, tfuntyp, tsublab,
tsubconst, tsubtype, tsubvar, tsubsub,
tsubstmt;
integer tstat;
declptr tscope;
} V13;
struct {
treeptr tidl, tbind;
attributes tattr;
} V14;
struct {
treeptr tparid, tparparm, tpartyp;
} V15;
struct {
treeptr tptrid;
boolean tptrflag;
} V16;
struct {
treeptr tscalid;
} V17;
struct {
treeptr tof;
} V18;
struct {
treeptr tlo, thi;
} V19;
struct {
treeptr tselct, tvrnt;
} V20;
struct {
treeptr tflist, tvlist;
idptr tuid;
declptr trscope;
} V21;
struct {
treeptr tcindx, tindtyp, tcelem;
idptr tcuid;
} V22;
struct {
treeptr taindx, taelem;
} V23;
struct {
treeptr tbegin;
} V24;
struct {
treeptr tlabno, tstmt;
} V25;
struct {
treeptr tlabel;
} V26;
struct {
treeptr tlhs, trhs;
} V27;
struct {
treeptr tglob, tloc, ttmp;
} V28;
struct {
treeptr tbrkid, tbrkxp;
} V29;
struct {
treeptr tcall, taparm;
} V30;
struct {
treeptr tifxp, tthen, telse;
} V31;
struct {
treeptr twhixp, twhistmt;
} V32;
struct {
treeptr treptstmt, treptxp;
} V33;
struct {
treeptr tforid, tfrom, tto, tforstmt;
boolean tincr;
} V34;
struct {
treeptr tcasxp, tcaslst, tcasother;
} V35;
struct {
treeptr tchocon, tchostmt;
} V36;
struct {
treeptr twithvar, twithstmt;
} V37;
struct {
treeptr texpw;
declptr tenv;
} V38;
struct {
treeptr tvariable, toffset;
} V39;
struct {
treeptr trecord, tfield;
} V40;
struct {
treeptr texpl, texpr;
} V41;
struct {
treeptr texps;
} V42;
struct {
symptr tsym;
} V43;
} U;
} treenode;
typedef enum { cabort, cbreak, ccontinue, cdefine,
cdefault, cdouble, cedata, cenum,
cetext, cextern, cfgetc, cfclose,
cfflush, cfloat, cfloor, cfprintf,
cfputc, cfread, cfscanf, cfwrite,
cgetc, cgetpid, cint, cinclude,
clong, clog, cmain, cmalloc,
cprintf, cpower, cputc, cread,
creturn, cregister, crewind, cscanf,
csetbits, csetword, csetptr, cshort,
csigned, csizeof, csprintf, cstdin,
cstdout, cstderr, cstrncmp, cstrncpy,
cstruct, cstatic, cswitch, ctypedef,
cundef, cungetc, cunion, cunlink,
cunsigned, cwrite } cnames;
typedef enum { ebadsymbol, elongstring, elongtokn, erange,
emanytokn, enotdeclid, emultdeclid, enotdecllab,
emultdecllab, emuldeflab, ebadstring, enulchr,
ebadchar, eeofcmnt, eeofstr, evarpar,
enew, esetbase, esetsize, eoverflow,
etree, etag, euprconf, easgnconf,
ecmpconf, econfconf, evrntfile, evarfile,
emanymachs, ebadmach } errors;
typedef struct { char A[machdeflen - 1 + 1]; } machdefstr;
typedef struct { struct S206 {
keyword wrd;
symtyp sym;
} A[keytablen + 1]; } T63;
typedef struct { strptr A[maxblkcnt + 1]; } T64;
typedef struct { idptr A[hashmax + 1]; } T65;
typedef struct { treeptr A[50]; } T66;
typedef struct { symptr A[50]; } T67;
typedef struct { treeptr A[11]; } T68;
typedef struct { unsigned char A[(int)(nnil) - (int)(nassign) + 1]; } T69;
typedef struct { idptr A[58]; } T70;
typedef struct { struct S193 {
integer lolim, hilim;
strindx typstr;
} A[maxmachdefs - 1 + 1]; } T71;
typedef struct { char A[15 + 1]; } T72;
typedef struct { setword S[2]; } bitset;
integer *G204_indnt;
integer *G202_doarrow;
boolean *G200_donearr;
boolean *G198_dropset;
boolean *G196_setused;
boolean *G194_conflag;
integer *G191_nelems;
treeptr *G189_vp;
treeptr *G187_tv;
symptr *G185_iq;
symptr *G183_ip;
unsigned char *G181_lastchr;
toknidx *G178_i;
toknbuf *G176_t;
boolean usemax, usejmps, usecase, usesets, useunion, usediff,
usemksub, useintr, usesge, usesle, useseq, usesne,
usememb, useins, usescpy, usecomp, usefopn, usescan,
usegetl, usenilp, usebool;
treeptr top;
treeptr setlst;
integer setcnt;
lexsym currsym;
T63 keytab;
T64 strstor;
strindx strfree;
strbidx strleft;
T65 idtab;
declptr symtab;
integer statlvl, maxlevel;
T66 deftab;
T67 defnams;
T68 typnods;
T69 pprio, cprio;
T70 ctable;
unsigned char nmachdefs;
T71 machdefs;
integer lineno, colno, lastcol, lastline;
toknbuf lasttok;
integer varno;
T72 hexdig;
void
prtmsg(m)
errors m;
{
static char user[] = "Error: ";
static char restr[] = "Implementation restriction: ";
static char inter[] = "* Internal error * ";
# define xtoklen 64
typedef struct { char A[xtoklen - 1 + 1]; } T73;
toknidx i;
T73 xtok;
switch (m) {
case ebadsymbol:
(void)fprintf(stderr, "%sUnexpected symbol\n", user), Putl(output, 1);
break ;
case ebadchar:
(void)fprintf(stderr, "%sBad character\n", user), Putl(output, 1);
break ;
case elongstring:
(void)fprintf(stderr, "%sToo long string\n", restr), Putl(output, 1);
break ;
case ebadstring:
(void)fprintf(stderr, "%sNewline in string or character\n", user), Putl(output, 1);
break ;
case eeofstr:
(void)fprintf(stderr, "%sEnd of file in string or character\n", user), Putl(output, 1);
break ;
case eeofcmnt:
(void)fprintf(stderr, "%sEnd of file in comment\n", user), Putl(output, 1);
break ;
case elongtokn:
(void)fprintf(stderr, "%sToo long identfier\n", restr), Putl(output, 1);
break ;
case emanytokn:
(void)fprintf(stderr, "%sToo many strings, identifiers or real numbers\n", restr), Putl(output, 1);
break ;
case enotdeclid:
(void)fprintf(stderr, "%sIdentifier not declared\n", user), Putl(output, 1);
break ;
case emultdeclid:
(void)fprintf(stderr, "%sIdentifier declared twice\n", user), Putl(output, 1);
break ;
case enotdecllab:
(void)fprintf(stderr, "%sLabel not declared\n", user), Putl(output, 1);
break ;
case emultdecllab:
(void)fprintf(stderr, "%sLabel declared twice\n", user), Putl(output, 1);
break ;
case emuldeflab:
(void)fprintf(stderr, "%sLabel defined twice\n", user), Putl(output, 1);
break ;
case evarpar:
(void)fprintf(stderr, "%sActual parameter not a variable\n", user), Putl(output, 1);
break ;
case enulchr:
(void)fprintf(stderr, "%sCannot handle nul-character in strings\n", restr), Putl(output, 1);
break ;
case enew:
(void)fprintf(stderr, "%sNew returned a nil-pointer\n", restr), Putl(output, 1);
break ;
case eoverflow:
(void)fprintf(stderr, "%sToken buffer overflowed\n", restr), Putl(output, 1);
break ;
case esetbase:
(void)fprintf(stderr, "%sCannot handle sets with base >> 0\n", restr), Putl(output, 1);
break ;
case esetsize:
(void)fprintf(stderr, "%sCannot handle sets with very large range\n", restr), Putl(output, 1);
break ;
case etree:
(void)fprintf(stderr, "%sBad tree structure\n", inter), Putl(output, 1);
break ;
case etag:
(void)fprintf(stderr, "%sCannot find tag\n", inter), Putl(output, 1);
break ;
case evrntfile:
(void)fprintf(stderr, "%sCannot initialize files in record variants\n", restr), Putl(output, 1);
break ;
case evarfile:
(void)fprintf(stderr, "%sCannot handle files in structured variables\n", restr), Putl(output, 1);
break ;
case euprconf:
(void)fprintf(stderr, "%sNo upper bound on conformant arrays\n", inter), Putl(output, 1);
break ;
case easgnconf:
(void)fprintf(stderr, "%sCannot assign conformant arrays\n", inter), Putl(output, 1);
break ;
case ecmpconf:
(void)fprintf(stderr, "%sCannot compare conformant arrays\n", inter), Putl(output, 1);
break ;
case econfconf:
(void)fprintf(stderr, "%sCannot handle nested conformat arrays\n", restr), Putl(output, 1);
break ;
case erange:
(void)fprintf(stderr, "%sCannot find C-type for integer-subrange\n", inter), Putl(output, 1);
break ;
case emanymachs:
(void)fprintf(stderr, "%sToo many machine integer types\n", restr), Putl(output, 1);
break ;
case ebadmach:
(void)fprintf(stderr, "%sBad name for machine integer type\n", inter), Putl(output, 1);
break ;
default:
Caseerror(Line);
}
if (lastline != 0) {
(void)fprintf(stderr, "Line %1d, col %1d:\n", lastline, lastcol), Putl(output, 1);
if (Member((unsigned)(m), Conset[0])) {
i = 1;
while ((i < xtoklen) && (lasttok.A[i - 1] != null)) {
xtok.A[i - 1] = lasttok.A[i - 1];
i = i + 1;
}
while (i < xtoklen) {
xtok.A[i - 1] = ' ';
i = i + 1;
}
xtok.A[xtoklen - 1] = ' ';
(void)fprintf(stderr, "Current symbol: %.64s\n", xtok.A), Putl(output, 1);
}
}
}
void fatal();
void error();
char
uppercase(c)
char c;
{
register char R75;
if ((c >= 'a') && (c <= 'z'))
R75 = (unsigned)(c) + (unsigned)('A') - (unsigned)('a');
else
R75 = c;
return R75;
}
char
lowercase(c)
char c;
{
register char R76;
if ((c >= 'A') && (c <= 'Z'))
R76 = (unsigned)(c) - (unsigned)('A') + (unsigned)('a');
else
R76 = c;
return R76;
}
void
gettokn(i, t)
strindx i;
toknbuf *t;
{
char c;
toknidx k;
strbidx j;
strptr p;
k = 1;
p = strstor.A[i / (maxstrblk + 1)];
j = i % (maxstrblk + 1);
do {
c = p->A[j];
t->A[k - 1] = c;
j = j + 1;
k = k + 1;
if (k == maxtoknlen) {
c = null;
t->A[maxtoknlen - 1] = null;
prtmsg(eoverflow);
}
} while (!(c == null));
}
void
puttokn(i, t)
strindx i;
toknbuf *t;
{
char c;
toknidx k;
strbidx j;
strptr p;
k = 1;
p = strstor.A[i / (maxstrblk + 1)];
j = i % (maxstrblk + 1);
do {
c = t->A[k - 1];
p->A[j] = c;
k = k + 1;
j = j + 1;
} while (!(c == null));
}
void
writetok(w)
toknbuf *w;
{
toknidx j;
j = 1;
while (w->A[j - 1] != null) {
Putchr(w->A[j - 1], output);
j = j + 1;
}
}
void
printtok(i)
strindx i;
{
toknbuf w;
gettokn(i, &w);
writetok(&w);
}
void
printid(ip)
idptr ip;
{
printtok(ip->istr);
}
void
printchr(c)
char c;
{
if ((c == quote) || (c == bslash))
(void)fprintf(output.fp, "%c%c%c%c", quote, bslash, c, quote), Putl(output, 0);
else
(void)fprintf(output.fp, "%c%c%c", quote, c, quote), Putl(output, 0);
}
void
printstr(i)
strindx i;
{
toknidx k;
char c;
toknbuf w;
gettokn(i, &w);
Putchr(cite, output);
k = 1;
while (w.A[k - 1] != null) {
c = w.A[k - 1];
k = k + 1;
if ((c == cite) || (c == bslash))
Putchr(bslash, output);
Putchr(c, output);
}
Putchr(cite, output);
}
treeptr
idup(ip)
treeptr ip;
{
register treeptr R77;
R77 = ip->U.V43.tsym->lsymdecl->tup;
return R77;
}
hashtyp
hashtokn(id)
toknbuf *id;
{
register hashtyp R78;
integer h;
toknidx i;
i = 1;
h = 0;
while (id->A[i - 1] != null) {
h = h + (unsigned)(id->A[i - 1]);
i = i + 1;
}
R78 = h % hashmax;
return R78;
}
strindx
savestr(t)
toknbuf *t;
{
register strindx R79;
toknidx k;
strindx i;
strbcnt j;
k = 1;
while (t->A[k - 1] != null)
k = k + 1;
if (k > strleft) {
if (strstor.A[maxblkcnt] != (strblk *)NIL)
error(emanytokn);
j = (strfree + maxstrblk) / (maxstrblk + 1);
strstor.A[j] = (strblk *)malloc((unsigned)(sizeof(*strstor.A[j])));
if (strstor.A[j] == (strblk *)NIL)
error(enew);
strfree = j * (maxstrblk + 1);
strleft = maxstrblk;
}
i = strfree;
strfree = strfree + k;
strleft = strleft - k;
puttokn(i, &(*t));
R79 = i;
return R79;
}
idptr
saveid(id)
toknbuf *id;
{
register idptr R80;
toknidx k;
idptr ip;
hashtyp h;
toknbuf t;
h = hashtokn(&(*id));
ip = idtab.A[h];
while (ip != (struct S59 *)NIL) {
gettokn(ip->istr, &t);
k = 1;
while (id->A[k - 1] == t.A[k - 1])
if (id->A[k - 1] == null)
goto L999;
else
k = k + 1;
ip = ip->inext;
}
ip = (struct S59 *)malloc((unsigned)(sizeof(*ip)));
if (ip == (struct S59 *)NIL)
error(enew);
ip->inref = 0;
ip->istr = savestr(&(*id));
ip->ihash = h;
ip->inext = idtab.A[h];
idtab.A[h] = ip;
L999:
R80 = ip;
return R80;
}
idptr
mkconc(sep, p, q)
char sep;
idptr p, q;
{
register idptr R81;
toknbuf w, x;
toknidx i, j;
gettokn(q->istr, &x);
j = 1;
while (x.A[j - 1] != null)
j = j + 1;
w.A[1 - 1] = null;
if (p != (struct S59 *)NIL)
gettokn(p->istr, &w);
i = 1;
while (w.A[i - 1] != null)
i = i + 1;
if (i + j + 2 >= maxtoknlen)
error(eoverflow);
if (sep == '>') {
w.A[i - 1] = '-';
i = i + 1;
}
if (sep != space) {
w.A[i - 1] = sep;
i = i + 1;
}
j = 1;
do {
w.A[i - 1] = x.A[j - 1];
i = i + 1;
j = j + 1;
} while (!(w.A[i - 1 - 1] == null));
R81 = saveid(&w);
return R81;
}
idptr mkuniqname();
void
dig(n)
integer n;
{
if (n > 0) {
dig(n / 10);
if ((*G178_i) == maxtoknlen)
error(eoverflow);
(*G176_t).A[(*G178_i) - 1] = n % 10 + (unsigned)('0');
(*G178_i) = (*G178_i) + 1;
}
}
idptr
mkuniqname(t)
toknbuf *t;
{
register idptr R82;
toknidx i;
toknbuf *F177;
toknidx *F179;
F179 = G178_i;
G178_i = &i;
F177 = G176_t;
G176_t = &(*t);
(*G178_i) = 1;
while ((*G176_t).A[(*G178_i) - 1] != null)
(*G178_i) = (*G178_i) + 1;
varno = varno + 1;
dig(varno);
(*G176_t).A[(*G178_i) - 1] = null;
R82 = saveid(&(*G176_t));
G176_t = F177;
G178_i = F179;
return R82;
}
idptr
mkvariable(c)
char c;
{
register idptr R83;
toknbuf t;
t.A[1 - 1] = c;
t.A[2 - 1] = null;
R83 = mkuniqname(&t);
return R83;
}
idptr
mkrename(c, ip)
char c;
idptr ip;
{
register idptr R84;
R84 = mkconc(uscore, mkvariable(c), ip);
return R84;
}
idptr
mkvrnt()
{
register idptr R85;
toknbuf t;
t.A[1 - 1] = 'U';
t.A[2 - 1] = '.';
t.A[3 - 1] = 'V';
t.A[4 - 1] = null;
R85 = mkuniqname(&t);
return R85;
}
void
checksymbol(ss)
symset ss;
{
if (!(Member((unsigned)(currsym.st), ss.S)))
error(ebadsymbol);
}
void nextsymbol();
char
nextchar()
{
register char R86;
char c;
if (Eof(input))
c = null;
else {
colno = colno + 1;
if (Eoln(input)) {
lineno = lineno + 1;
colno = 0;
}
c = Getchr(input);
if (echo)
if (colno == 0)
Putchr('\n', output);
else
Putchr(c, output);
if (c == tab1)
colno = ((colno / tabwidth) + 1) * tabwidth;
}
if ((*G181_lastchr) > 0) {
lasttok.A[(*G181_lastchr) - 1] = c;
(*G181_lastchr) = (*G181_lastchr) + 1;
}
R86 = c;
return R86;
}
char
peekchar()
{
register char R87;
if (Eof(input))
R87 = null;
else
R87 = input.buf;
return R87;
}
void nexttoken();
boolean
idchar(c)
char c;
{
register boolean R88;
R88 = (boolean)((c >= 'a') && (c <= 'z') || (c >= '0') && (c <= '9') || (c >= 'A') && (c <= 'Z') || (c == uscore));
return R88;
}
boolean
numchar(c)
char c;
{
register boolean R89;
R89 = (boolean)((c >= '0') && (c <= '9'));
return R89;
}
integer
numval(c)
char c;
{
register integer R90;
R90 = (unsigned)(c) - (unsigned)('0');
return R90;
}
symtyp
keywordcheck(w, l)
toknbuf *w;
toknidx l;
{
register symtyp R91;
register unsigned char n;
unsigned char i, j, k;
keyword wrd;
symtyp kwc;
if ((l > 1) && (l < keywordlen)) {
wrd = keytab.A[keytablen].wrd;
{
unsigned char B44 = 1,
B45 = l;
if (B44 <= B45)
for (n = B44; ; n++) {
wrd.A[n - 1] = w->A[n - 1];
if (n == B45) break;
}
}
i = 0;
j = keytablen;
while (j > i) {
k = (i + j) / 2;
if (Cmpstr(keytab.A[k].wrd.A, wrd.A) >= 0)
j = k;
else
i = k + 1;
}
if (Cmpstr(keytab.A[j].wrd.A, wrd.A) == 0)
kwc = keytab.A[j].sym;
else
kwc = sid;
} else
kwc = sid;
R91 = kwc;
return R91;
}
void
nexttoken(realok)
boolean realok;
{
char c;
integer n;
boolean ready;
toknidx wl;
toknbuf wb;
(*G181_lastchr) = 0;
do {
c = nextchar();
if (c == '{') {
do {
c = nextchar();
if (diffcomm)
ready = (boolean)(c == '}');
else
ready = (boolean)(((c == '*') && (peekchar() == ')')) || (c == '}'));
} while (!(ready || Eof(input)));
if (Eof(input) && !ready)
error(eeofcmnt);
if ((c == '*') && !Eof(input))
c = nextchar();
c = space;
} else
if ((c == '(') && (peekchar() == '*')) {
c = nextchar();
do {
c = nextchar();
if (diffcomm)
ready = (boolean)((c == '*') && (peekchar() == ')'));
else
ready = (boolean)(((c == '*') && (peekchar() == ')')) || (c == '}'));
} while (!(ready || Eof(input)));
if (Eof(input) && !ready)
error(eeofcmnt);
if ((c == '*') && !Eof(input))
c = nextchar();
c = space;
}
} while (!((c != space) && (c != tab1)));
lasttok.A[1 - 1] = c;
(*G181_lastchr) = 2;
lastcol = colno;
lastline = lineno;
if (c < okchr)
c = badchr;
{
register struct S180 *W46 = &currsym;
if (Eof(input)) {
lasttok.A[1 - 1] = '*';
lasttok.A[2 - 1] = 'E';
lasttok.A[3 - 1] = 'O';
lasttok.A[4 - 1] = 'F';
lasttok.A[5 - 1] = '*';
(*G181_lastchr) = 6;
W46->st = seof;
} else
switch (c) {
case '|': case '`': case '~': case '}':
case 92: case 95: case 63:
error(ebadchar);
break ;
case 'a': case 'b': case 'c': case 'd':
case 'e': case 'f': case 'g': case 'h':
case 'i': case 'j': case 'k': case 'l':
case 'm': case 'n': case 'o': case 'p':
case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z': case 'A': case 'B':
case 'C': case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N':
case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V':
case 'W': case 'X': case 'Y': case 'Z':
wb.A[1 - 1] = lowercase(c);
wl = 2;
while ((wl < maxtoknlen) && idchar(peekchar())) {
wb.A[wl - 1] = lowercase(nextchar());
wl = wl + 1;
}
if (wl >= maxtoknlen) {
lasttok.A[(*G181_lastchr) - 1] = null;
error(elongtokn);
}
wb.A[wl - 1] = null;
W46->st = keywordcheck(&wb, wl - 1);
if (W46->st == sid)
W46->U.V1.vid = saveid(&wb);
break ;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
case '8': case '9':
wb.A[1 - 1] = c;
wl = 2;
n = numval(c);
while (numchar(peekchar())) {
c = nextchar();
n = n * 10 + numval(c);
wb.A[wl - 1] = c;
wl = wl + 1;
}
W46->st = sinteger;
W46->U.V3.vint = n;
if (realok) {
if (peekchar() == '.') {
W46->st = sreal;
wb.A[wl - 1] = nextchar();
wl = wl + 1;
while (numchar(peekchar())) {
wb.A[wl - 1] = nextchar();
wl = wl + 1;
}
}
c = peekchar();
if ((c == 'e') || (c == 'E')) {
W46->st = sreal;
c = nextchar();
wb.A[wl - 1] = xpnent;
wl = wl + 1;
c = peekchar();
if ((c == '-') || (c == '+')) {
wb.A[wl - 1] = nextchar();
wl = wl + 1;
}
while (numchar(peekchar())) {
wb.A[wl - 1] = nextchar();
wl = wl + 1;
}
}
if (W46->st == sreal) {
wb.A[wl - 1] = null;
W46->U.V4.vflt = savestr(&wb);
}
}
break ;
case '(':
if (peekchar() == '.') {
c = nextchar();
W46->st = slbrack;
} else
W46->st = slpar;
break ;
case ')':
W46->st = srpar;
break ;
case '[':
W46->st = slbrack;
break ;
case ']':
W46->st = srbrack;
break ;
case '.':
if (peekchar() == '.') {
c = nextchar();
W46->st = sdotdot;
} else
if (peekchar() == ')') {
c = nextchar();
W46->st = srbrack;
} else
W46->st = sdot;
break ;
case ';':
W46->st = ssemic;
break ;
case ':':
if (peekchar() == '=') {
c = nextchar();
W46->st = sassign;
} else
W46->st = scolon;
break ;
case ',':
W46->st = scomma;
break ;
case '@': case '^':
W46->st = sarrow;
break ;
case '=':
W46->st = seq;
break ;
case '<':
if (peekchar() == '=') {
c = nextchar();
W46->st = sle;
} else
if (peekchar() == '>') {
c = nextchar();
W46->st = sne;
} else
W46->st = slt;
break ;
case '>':
if (peekchar() == '=') {
c = nextchar();
W46->st = sge;
} else
W46->st = sgt;
break ;
case '+':
W46->st = splus;
break ;
case '-':
W46->st = sminus;
break ;
case '*':
W46->st = smul;
break ;
case '/':
W46->st = squot;
break ;
case 39:
wl = 0;
ready = false;
do {
if (Eoln(input)) {
lasttok.A[(*G181_lastchr) - 1] = null;
error(ebadstring);
}
c = nextchar();
if (c == quote)
if (peekchar() == quote)
c = nextchar();
else
ready = true;
if (c == null) {
if (Eof(input))
error(eeofstr);
lasttok.A[(*G181_lastchr) - 1] = null;
error(enulchr);
}
if (!ready) {
wl = wl + 1;
if (wl >= maxtoknlen) {
lasttok.A[(*G181_lastchr) - 1] = null;
error(elongstring);
}
wb.A[wl - 1] = c;
}
} while (!(ready));
if (wl == 1) {
W46->st = schar;
W46->U.V2.vchr = wb.A[1 - 1];
} else {
wl = wl + 1;
if (wl >= maxtoknlen) {
lasttok.A[(*G181_lastchr) - 1] = null;
error(elongstring);
}
wb.A[wl - 1] = null;
W46->st = sstring;
W46->U.V5.vstr = savestr(&wb);
}
break ;
default:
Caseerror(Line);
}
}
if ((*G181_lastchr) == 0)
(*G181_lastchr) = 1;
lasttok.A[(*G181_lastchr) - 1] = null;
}
void
nextsymbol(ss)
symset ss;
{
unsigned char lastchr;
unsigned char *F182;
F182 = G181_lastchr;
G181_lastchr = &lastchr;
nexttoken((boolean)(Member((unsigned)(sreal), ss.S)));
checksymbol(ss);
G181_lastchr = F182;
}
treeptr
typeof(tp)
treeptr tp;
{
register treeptr R92;
treeptr tf, tq;
tq = tp;
tf = tq->ttype;
while (tf == (struct S61 *)NIL) {
switch (tq->tt) {
case nchar:
tf = typnods.A[(int)(tchar)];
break ;
case ninteger:
tf = typnods.A[(int)(tinteger)];
break ;
case nreal:
tf = typnods.A[(int)(treal)];
break ;
case nstring:
tf = typnods.A[(int)(tstring)];
break ;
case nnil:
tf = typnods.A[(int)(tnil)];
break ;
case nid:
tq = idup(tq);
if (tq == (struct S61 *)NIL)
fatal(etree);
break ;
case ntype: case nvar: case nconst: case nfield:
case nvalpar: case nvarpar:
tq = tq->U.V14.tbind;
break ;
case npredef: case nptr: case nscalar: case nrecord:
case nconfarr: case narray: case nfileof: case nsetof:
tf = tq;
break ;
case nsubrange:
if (tq->tup->tt == nconfarr)
tf = tq->tup->U.V22.tindtyp;
else
tf = tq;
break ;
case ncall:
tf = typeof(tq->U.V30.tcall);
if (tf == typnods.A[(int)(tpoly)])
tf = typeof(tq->U.V30.taparm);
break ;
case nfunc:
tq = tq->U.V13.tfuntyp;
break ;
case nparfunc:
tq = tq->U.V15.tpartyp;
break ;
case nproc: case nparproc:
tf = typnods.A[(int)(tnone)];
break ;
case nvariant: case nlabel: case npgm: case nempty:
case nbegin: case nlabstmt: case nassign: case npush:
case npop: case nif: case nwhile: case nrepeat:
case nfor: case ncase: case nchoise: case ngoto:
case nwith: case nwithvar:
fatal(etree);
break ;
case nformat: case nrange:
tq = tq->U.V41.texpl;
break ;
case nplus: case nminus: case nmul:
tf = typeof(tq->U.V41.texpl);
if (tf == typnods.A[(int)(tinteger)])
tf = typeof(tq->U.V41.texpr);
else
if (tf->tt == nsetof)
tf = typnods.A[(int)(tset)];
break ;
case numinus: case nuplus:
tq = tq->U.V42.texps;
break ;
case nmod: case ndiv:
tf = typnods.A[(int)(tinteger)];
break ;
case nquot:
tf = typnods.A[(int)(treal)];
break ;
case neq: case nne: case nlt: case nle:
case ngt: case nge: case nin: case nor:
case nand: case nnot:
tf = typnods.A[(int)(tboolean)];
break ;
case nset: